<template>
  <div>
    <a-card :bordered="false">
      <div class="table-page-search-wrapper">
        <a-form layout="horizontal" >
          <a-row :gutter="8">
            <a-col :md="8" :sm="24">
              <a-form-item label="任务名" :labelCol="labelCol" :wrapperCol="wrapperCol">
                <a-input v-model="queryParam.jobName" placeholder="精确查询"/>
              </a-form-item>
            </a-col>
            <a-col :md="8" :sm="24">
              <a-form-item label="任务描述" :labelCol="labelCol" :wrapperCol="wrapperCol">
                <a-input v-model="queryParam.title" placeholder="支持模糊查询"/>
              </a-form-item>
            </a-col>
            <template v-if="advanced">
              <a-col :md="8" :sm="24">
                <a-form-item label="任务状态" :labelCol="labelCol" :wrapperCol="wrapperCol">
                  <a-select v-model="queryParam.triggerState" placeholder="单选" allowClear >
                    <a-select-option v-for="item in dictData.triggerState" :key="item.dictKey" :value="item.dictKey">{{ item.dictValue }}</a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
            </template>
            <a-col :md="!advanced && 8 || 24" :sm="24">
              <span class="table-page-search-submitButtons" :style="advanced && { float: 'right', overflow: 'hidden' } || {} ">
                <a-button type="primary" @click="() =>{this.findListBtn()}">查询</a-button>
                <a-button style="margin-left: 8px" @click="() => {this.clearAll()}">重置</a-button>
                <a @click="toggleAdvanced" style="margin-left: 8px">
                  {{ advanced ? '收起' : '展开' }}
                  <a-icon :type="advanced ? 'up' : 'down'"/>
                </a>
              </span>
            </a-col>
          </a-row>
        </a-form>
      </div>
      <vxe-table
        class="vxe-table-antd"
        resizable
        show-overflow
        ref="listTable"
        stripe
        border
        highlight-hover-row
        highlight-current-row
        highlight-hover-column
        highlight-current-column
        highlight-cell
        height="400"
        size="small"
        :data="tableData"
        :loading="loading"
        :start-index="(tablePage.currentPage - 1) * tablePage.pageSize"
        :pager-config="tablePage"
        @page-change="handlePageChange">
        <vxe-table-column type="seq" width="80" fixed="left" align="center" title="序号" ></vxe-table-column>
        <vxe-table-column field="jobName" title="任务名" width="200" fixed="left" align="center"></vxe-table-column>
        <vxe-table-column field="jobGroup" title="任务组" width="200" align="center"></vxe-table-column>
        <vxe-table-column field="description" title="任务描述" width="300" align="center"></vxe-table-column>
        <vxe-table-column
          field="triggerState"
          title="任务状态"
          width="100"
          align="center">
          <template v-slot="{ row }">
            <a-badge v-if="row.triggerState === 'WAITING'" status="success" text="等待" />
            <a-badge v-if="row.triggerState === 'PAUSED'" status="warning" text="暂停" />
            <a-badge v-if="row.triggerState === 'ACQUIRED'" status="processing" text="正在执行" />
            <a-badge v-if="row.triggerState === 'BLOCKED'" status="default" text="阻塞" />
            <a-badge v-if="row.triggerState === 'ERROR'" status="error" text="错误" />
          </template>
        </vxe-table-column>
        <vxe-table-column field="parameter" title="任务参数" width="300" align="center"></vxe-table-column>
        <vxe-table-column field="schedName" title="调度名称" width="100" align="center"></vxe-table-column>
        <vxe-table-column field="jobClassName" title="任务所在类路径" width="300" align="center"></vxe-table-column>
        <vxe-table-column field="cronExpression" title="执行策略" width="150" align="center"></vxe-table-column>
        <vxe-table-column field="prevFireTime" title="上次触发时间" width="150" align="center" :formatter="formatTime"></vxe-table-column>
        <vxe-table-column field="nextFireTime" title="下次触发时间" width="150" align="center" :formatter="formatTime"></vxe-table-column>
        <vxe-table-column field="startTime" title="开始时间" width="150" align="center" :formatter="formatTime"></vxe-table-column>
        <vxe-table-column field="endTime" title="结束时间" width="150" align="center" :formatter="formatTime"></vxe-table-column>
        <vxe-table-column field="priority" title="优先级" width="150" align="center"></vxe-table-column>
        <vxe-table-column field="timeZoneId" title="时区" width="150" align="center"></vxe-table-column>
        <vxe-table-column
          field="operation"
          title="操作"
          fixed="right"
          width="150"
          align="center"
          show-overflow>
          <template v-slot="{ row }">
            <a-dropdown :trigger="['click']">
              <a class="ant-dropdown-link" href="#"> 操作 <a-icon type="down" /> </a>
              <a-menu slot="overlay" style="text-align:center">
                <a-menu-item key="0">
                  <a href="javascript:;" class="ant-dropdown-link" @click="openUpdateJobPage(row)" ><span>修改</span></a>
                </a-menu-item>
                <a-menu-item key="1">
                  <a href="javascript:;" class="ant-dropdown-link" @click="deleteJob(row)" ><span>删除</span></a>
                </a-menu-item>
                <a-menu-item key="2">
                  <a href="javascript:;" class="ant-dropdown-link" @click="triggerJob(row)" ><span>立即执行</span></a>
                </a-menu-item>
                <a-menu-item key="3" v-if="row.triggerState === 'WAITING'">
                  <a href="javascript:;" class="ant-dropdown-link" @click="pauseJob(row)" ><span>暂停</span></a>
                </a-menu-item>
                <a-menu-item key="4" v-if="row.triggerState === 'PAUSED'">
                  <a href="javascript:;" class="ant-dropdown-link" @click="resumeJob(row)" ><span>恢复</span></a>
                </a-menu-item>
                <a-menu-item key="5" v-if="row.triggerState === 'ERROR'">
                  <a href="javascript:;" class="ant-dropdown-link" @click="resetTriggerFromErrorState(row)" ><span>错误重置</span></a>
                </a-menu-item>
              </a-menu>
            </a-dropdown>
          </template>
        </vxe-table-column>
      </vxe-table>
    </a-card>
    <a-modal
      :title="modalTitle"
      centered
      style="top: 20px;"
      width="65%"
      destroyOnClose
      v-model="visible"
      cancelText="关闭"
      okText="保存"
      @ok="saveQuartz"
    >
      <quartz-form ref="quartzPage" :quartzInfo="selectRow" />
    </a-modal>
    <footer-tool-bar>
      <a-button style="margin-left: 8px;" type="primary" icon="plus" @click="() =>{this.openAddJobPage()}">新增任务</a-button>
      <a-button style="margin-left: 8px" type="primary" icon="poweroff" @click="() =>{this.startJobs()}">启动所有</a-button>
      <a-button style="margin-left: 8px" type="danger" icon="pause-circle" @click="() =>{this.pauseAll()}">暂停所有</a-button>
      <a-button style="margin-left: 8px" type="primary" icon="play-circle" @click="() =>{this.resumeAll()}">恢复所有</a-button>
    </footer-tool-bar>
  </div>
</template>

<script>
import { getQuartzList, getBatchDict,addQuartzJob,updateQuartzJob,deleteQuartzJob,pauseQuartzJob,resumeQuartzJob,pauseAllQuartz,resumeAllQuartz,startJobsQuartz,shutdownJobsQuartz,resetTriggerFromErrorState,triggerJobQuartz } from "@/services/system/api"
import { formatDate } from '@/utils/util'
import modal from 'ant-design-vue/es/modal'
import moment from 'moment'
import QuartzForm from '@/pages/system/form/QuartzForm'
import FooterToolBar from '@/components/FooterToolbar'

export default {
  name: 'QuartzManager',
  components: {
    QuartzForm,
    FooterToolBar
  },
  data () {
    return {
      description: '定时任务管理',
      dictData: {},
      endOpen: false,
      visible: false,
      labelCol: {
        xs: { span: 24 },
        sm: { span: 7 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 17 }
      },
      form: null,
      // 高级搜索 展开/关闭
      advanced: false,
      // 查询参数
      queryParam: {},
      // 表头
      loading: false,
      tablePage: {
        total: 0,
        currentPage: 1,
        pageNum: 1,
        pageSize: 20
      },
      tableData: [],
      selectRow: {},
      modalTitle: '操作',
      updateFlag: false
    }
  },
  created () {
    // 数据初始化
    // 数据字典初始化
    const params = {}
    params.dictFields = 'triggerState'
    this.$http.post(getBatchDict,params).then(res => {
      this.dictData = res.result
    })
    this.findList()
  },
  methods: {
    moment,
    toggleAdvanced () {
      this.advanced = !this.advanced
    },
    handlePageChange ({ currentPage, pageSize }) {
      this.tablePage.currentPage = currentPage
      this.tablePage.pageNum = currentPage
      this.tablePage.pageSize = pageSize
      this.findList()
    },
    findListBtn () {
      this.tablePage.currentPage = 1
      this.tablePage.pageNum = 1
      this.findList()
    },
    // 列表查询
    findList () {
      this.loading = true
      const params = Object.assign(this.queryParam, this.tablePage)
      setTimeout(() => {
        this.$http.post(getQuartzList,params).then((res) => {
          const data = res.result.list
          this.tableData = data
          this.tablePage.total = res.result.total
          this.tablePage.currentPage = res.result.pageNum
          this.tablePage.pageNum = res.result.pageNum
          this.tablePage.pageSize = res.result.pageSize
          this.loading = false
        }).catch(() => {
          this.loading = false
        })
      }, 20)
    },
    clearAll () {
      this.queryParam = {}
      this.findList()
    },
    openAddJobPage () {
      this.modalTitle = '新增任务'
      this.selectRow = {}
      this.updateFlag = false
      this.visible = true
    },
    openUpdateJobPage (row) {
      this.modalTitle = '修改任务'
      const info = Object.assign({}, row)
      this.updateFlag = true
      info.updateFlag = true
      this.selectRow = info
      this.visible = true
    },
    deleteJob (row) {
      setTimeout(() => {
        this.$http.post(deleteQuartzJob,row).then(() => {
          modal.info({ title: '成功提示', content: '删除成功' })
          this.findList()
        }).catch(() => {
        })
      }, 20)
    },
    triggerJob (row) {
      setTimeout(() => {
        this.$http.post(triggerJobQuartz,row).then((res) => {
          modal.info({ title: '成功提示', content: '开始执行任务' })
          this.updateTable(res.result)
        }).catch(() => {
        })
      }, 20)
    },
    pauseJob (row) {
      setTimeout(() => {
        this.$http.post(pauseQuartzJob,row).then((res) => {
          modal.info({ title: '成功提示', content: '暂停成功' })
          this.updateTable(res.result)
        }).catch(() => {
        })
      }, 20)
    },
    resumeJob (row) {
      setTimeout(() => {
        this.$http.post(resumeQuartzJob,row).then((res) => {
          modal.info({ title: '成功提示', content: '恢复成功' })
          this.updateTable(res.result)
        }).catch(() => {
        })
      }, 20)
    },
    resetTriggerFromErrorState (row) {
      setTimeout(() => {
        this.$http.post(resetTriggerFromErrorState,row).then((res) => {
          modal.info({ title: '成功提示', content: '重置错误成功' })
          this.updateTable(res.result)
        }).catch(() => {
        })
      }, 20)
    },
    startJobs () {
      setTimeout(() => {
        this.$http.post(startJobsQuartz,{}).then(() => {
          modal.info({ title: '成功提示', content: '启动所有成功' })
          this.findList()
        }).catch(() => {
        })
      }, 20)
    },
    shutdownJobs () {
      setTimeout(() => {
        this.$http.post(shutdownJobsQuartz,{}).then(() => {
          modal.info({ title: '成功提示', content: '停止所有成功' })
          this.findList()
        }).catch(() => {
        })
      }, 20)
    },
    pauseAll () {
      setTimeout(() => {
        this.$http.post(pauseAllQuartz,{}).then(() => {
          modal.info({ title: '成功提示', content: '暂停所有成功' })
          this.findList()
        }).catch(() => {
        })
      }, 20)
    },
    resumeAll () {
      setTimeout(() => {
        this.$http.post(resumeAllQuartz,{}).then(() => {
          modal.info({ title: '成功提示', content: '恢复所有成功' })
          this.findList()
        }).catch(() => {
        })
      }, 20)
    },
    saveQuartz () {
      // 表单验证
      const { $refs: { quartzPage } } = this
      const quartzPageForm = new Promise((resolve, reject) => {
        quartzPage.form.validateFields((err, values) => {
          if (err) {
            reject(err)
            return
          }
          resolve(values)
        })
      })
      this.errors = []
      Promise.all([quartzPageForm]).then(values => {
        if (values && values.length > 0) {
          const quartz = values[0]
          quartz.jobDescription = quartz.title
          quartz.description = quartz.title
          if (this.updateFlag) {
            setTimeout(() => {
              this.$http.post(updateQuartzJob,quartz).then((res) => {
                modal.info({ title: '成功提示', content: '修改成功' })
                this.visible = false
                this.updateTable(res.result)
              }).catch(() => {
              })
            }, 20)
          } else {
            setTimeout(() => {
              this.$http.post(addQuartzJob,quartz).then(() => {
                modal.info({ title: '成功提示', content: '新增成功' })
                this.visible = false
                this.findList()
              }).catch(() => {
              })
            }, 20)
          }
        }
      }).catch(() => {
        const errors = Object.assign({}, quartzPage.form.getFieldsError())
        const tmp = { ...errors }
        this.errorList(tmp)
      })
    },
    updateTable (quartz) {
      const data = [...this.tableData]
      data.forEach((item, index, arr) => {
        if (item.jobName === quartz.jobName) {
          arr.splice(index, 1, quartz)
          return item
        }
      })
      this.tableData = data
    },
    errorList (errors) {
      if (!errors || errors.length === 0) {
        return
      }
      this.errors = Object.keys(errors)
        .filter(key => errors[key])
        .map(key => ({
          key: key,
          message: errors[key][0]
        }))
    },
    formatTime ({ cellValue }) {
      if (cellValue) {
        if (cellValue === -1) {
          return '未触发'
        } else if (cellValue === 0) {
          return ''
        }
        return formatDate(cellValue)
      }
    }
  },
  watch: {
    /*
      'selectedRows': function (selectedRows) {
        this.needTotalList = this.needTotalList.map(item => {
          return {
            ...item,
            total: selectedRows.reduce( (sum, val) => {
              return sum + val[item.dataIndex]
            }, 0)
          }
        })
      }
      */
  }
}
</script>
<style lang="less" scoped>
@import "~ant-design-vue/lib/style/themes/default.less";
.table-operation-color {
  color : @primary-color
}
</style>
